home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / LAPBTIME.C < prev    next >
Encoding:
C/C++ Source or Header  |  1997-09-06  |  4.3 KB  |  186 lines

  1. /* LAPB (AX.25) timer recovery routines
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  *
  4.  * Mods by G1EMM
  5.  */
  6. #include "global.h"
  7. #ifdef AX25
  8. #include "mbuf.h"
  9. #include "ax25.h"
  10.  
  11. #if !defined(_lint)
  12. static char rcsid[] OPTIONAL = "$Id: lapbtime.c,v 1.10 1997/09/07 00:31:16 root Exp root $";
  13. #endif
  14.  
  15. static void tx_enq (struct ax25_cb * axp);
  16.  
  17. int lapbtimertype = 0;        /* default to binary exponential */
  18.  
  19.  
  20. /* Called whenever timer T1 expires */
  21. void
  22. recover (void *p)
  23. {
  24. register struct ax25_cb *axp = (struct ax25_cb *) p;
  25. long waittime = dur_timer (&axp->t1);
  26. long maxwait;
  27.  
  28.     axp->flags.retrans = 1;
  29.     axp->retries++;
  30.  
  31.     /* update the counters for retries out */
  32.     if (axp && axp->iface)
  33.         axp->iface->axcnt.retries++;
  34.  
  35.     if (!axp || !axp->iface || !axp->iface->ax25)
  36.         return;
  37.         
  38.     switch (axp->iface->ax25->lapbtimertype) {
  39.         case 2:    /* original backoff mode*/
  40.             set_timer (&axp->t1, axp->srt * 2);
  41.             break;
  42.         case 1:    /* linear backoff mode */
  43.             if ((1L << axp->retries) < axp->iface->ax25->blimit)
  44.                 set_timer (&axp->t1, dur_timer (&axp->t1) + axp->srt);
  45.             break;
  46.         case 0:    /* exponential backoff mode */
  47.             if ((1L << axp->retries) < axp->iface->ax25->blimit)
  48.                 set_timer (&axp->t1, dur_timer (&axp->t1) * 2);
  49.             break;
  50.         default:
  51.             break;
  52.     }
  53.     /* IF a maximum is set, and we surpass it, use the maximum */
  54.     maxwait = axp->iface->ax25->maxwait;
  55.  
  56.     if (maxwait && (waittime > maxwait))
  57.         waittime = maxwait;
  58.  
  59.     set_timer (&axp->t1, waittime);
  60.  
  61.     switch (axp->state) {
  62.         case LAPB_SETUP:
  63.             if (axp->n2 != 0 && axp->retries > axp->n2) {
  64. #ifdef NETROM
  65.                 nr_derate (axp);
  66. #endif
  67.                 free_q (&axp->txq);
  68.                 axp->reason = LB_TIMEOUT;
  69.                 lapbstate (axp, LAPB_DISCONNECTED);
  70.             } else {
  71.                 (void) sendctl (axp, LAPB_COMMAND, SABM | PF);
  72.                 start_timer (&axp->t1);
  73.             }
  74.             break;
  75.         case LAPB_DISCPENDING:
  76.             if (axp->n2 != 0 && axp->retries > axp->n2) {
  77. #ifdef NETROM
  78.                 nr_derate (axp);
  79. #endif
  80.                 axp->reason = LB_TIMEOUT;
  81.                 lapbstate (axp, LAPB_DISCONNECTED);
  82.             } else {
  83.                 (void) sendctl (axp, LAPB_COMMAND, DISC | PF);
  84.                 start_timer (&axp->t1);
  85.             }
  86.             break;
  87.         case LAPB_CONNECTED:
  88.         case LAPB_RECOVERY:
  89.             if (axp->n2 != 0 && axp->retries > axp->n2) {
  90.                 /* Give up */
  91. #ifdef NETROM
  92.                 nr_derate (axp);
  93. #endif
  94.                 (void) sendctl (axp, LAPB_RESPONSE, DM | PF);
  95.                 free_q (&axp->txq);
  96.                 axp->reason = LB_TIMEOUT;
  97.                 lapbstate (axp, LAPB_DISCONNECTED);
  98.             } else {
  99.                 /* Transmit poll */
  100.                 tx_enq (axp);
  101.                 lapbstate (axp, LAPB_RECOVERY);
  102.             }
  103.             break;
  104.         default:
  105.             break;
  106.     }
  107. }
  108.  
  109.  
  110.  
  111. /* Send a poll (S-frame command with the poll bit set) */
  112. void
  113. pollthem (void *p)
  114. {
  115. register struct ax25_cb *axp;
  116.  
  117.     axp = (struct ax25_cb *) p;
  118.     if (axp->proto == V1)
  119.         return;        /* Not supported in the old protocol */
  120.     switch (axp->state) {
  121.         case LAPB_RECOVERY:
  122.         case LAPB_CONNECTED:
  123.             axp->retries = 0;
  124.             tx_enq (axp);
  125.             lapbstate (axp, LAPB_RECOVERY);
  126.             break;
  127.         default:
  128.             break;
  129.     }
  130. }
  131.  
  132.  
  133.  
  134. /* Called whenever timer T4 (link rudundancy timer) expires */
  135. void
  136. redundant (void *p)
  137. {
  138. register struct ax25_cb *axp;
  139.  
  140.     axp = (struct ax25_cb *) p;
  141.     switch (axp->state) {
  142.         case LAPB_CONNECTED:
  143.         case LAPB_RECOVERY:
  144.             axp->retries = 0;
  145.             (void) sendctl (axp, LAPB_COMMAND, DISC | PF);
  146.             start_timer (&axp->t1);
  147.             free_q (&axp->txq);
  148.             lapbstate (axp, LAPB_DISCPENDING);
  149.             break;
  150.         default:
  151.             break;
  152.     }
  153. }
  154.  
  155.  
  156.  
  157. /* Transmit query */
  158. static void
  159. tx_enq (register struct ax25_cb *axp)
  160. {
  161. char ctl;
  162. struct mbuf *bp;
  163.  
  164.     /* I believe that retransmitting the oldest unacked
  165.      * I-frame tends to give better performance than polling,
  166.      * as long as the frame isn't too "large", because
  167.      * chances are that the I frame got lost anyway.
  168.      * This is an option in LAPB, but not in the official AX.25.
  169.      */
  170.     if (axp->txq != NULLBUF && axp->pthresh != 65535 && (len_p (axp->txq) < axp->pthresh || axp->proto == V1)) {
  171.         /* Retransmit oldest unacked I-frame */
  172.         (void) dup_p (&bp, axp->txq, 0, len_p (axp->txq));
  173.         ctl = PF | I | (((axp->vs - axp->unack) & MMASK) << 1) | (axp->vr << 5);    /*lint !e701 !e734 */
  174.         (void) sendframe (axp, LAPB_COMMAND, ctl, bp);
  175.     } else {
  176.         ctl = len_p (axp->rxq) >= axp->window ? RNR | PF : RR | PF;
  177.         (void) sendctl (axp, LAPB_COMMAND, ctl);
  178.     }
  179.     axp->response = 0;
  180.     stop_timer (&axp->t3);
  181.     start_timer (&axp->t1);
  182. }
  183.  
  184. #endif /* AX25 */
  185.  
  186.